#include <iostream>
#include <string>
#include <memory>
#include <ctime>
#include "Protocol.hpp"
#include "Socket.hpp"
#include "InterAddr.hpp"

using namespace protocol_ns;
using namespace socket_ns;

void Usage(std::string proc)
{
    std::cout << "Usage\n\t" << proc << " local_ip local_port\n"
              << std::endl;
}

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        Usage(argv[0]);
        exit(1);
    }

    std::string serverip = argv[1];
    uint16_t serverport = std::stoi(argv[2]);

    InterAddr serveraddr(serverip, serverport);
    Factory factory;
    std::unique_ptr<Socket> cli = std::make_unique<TcpSocket>();
    bool res = cli->BuidClientSocket(serveraddr);
    std::string inbuffer;
    while (res)
    {
        // 1. 构建一个请求

        std::string str;
        for (int i = 0; i < 5; i++)
        {
	    sleep(1);
            auto req = factory.BuildRequest();
            // 2. 对请求进行序列化

            std::string send_str;
            req->Serialize(&send_str);

            std::cout << "Serialize:\n"
                      << send_str << std::endl;

            // 3. 添加长度报头
            send_str = Encode(send_str);
            std::cout << "Encode:\n"
                      << send_str << std::endl;
            str += send_str;
        }
        // 4. "len"/r/n"{   }"/r/n"
        // 发数据
        cli->Send(str);

        // 5. 读取应答
        int n = cli->Recv(&inbuffer);
        if (n <= 0)
        {
            break;
        }
        // 根据报头长度拿到数据
        std::string package = Decode(inbuffer);
        if (package.empty())
            continue;

        // 6. 这里能保证package一定是一个完成的应答
        auto resp = factory.BuildResponse();
        // 6.1 反序列化
        resp->Deserialize(package);

        // 7. 拿到了结构化的应答
        std::cout << resp->_result << "[" << resp->_code << "]" << std::endl;
    }
    return 0;
}
